<?php


namespace app\cms\community;

use app\cms\dto\bindPhoneOrEmail;
use app\cms\dto\changePassword;
use app\cms\dto\registerForm;
use app\cms\dto\userInfo;
use app\cms\model\userModel;
use app\cms\model\userOauthKeyModel;
use iflow\auth\Authorize\AuthAnnotation;
use iflow\facade\Session;
use iflow\Response;
use iflow\Router\Controller;
use iflow\Router\implement\Request\{ GetMapping, PostMapping, DeleteMapping };


#[Controller('cms/api/community/user')]
class user
{

    /**
     * 用户账户登录
     * @param userInfo $userInfo
     * @return Response
     */
    #[PostMapping]
    public function login(userInfo $userInfo): Response
    {
        return (new userModel()) -> login($userInfo);
    }

    /**
     * 获取指定用户信息
     * @param int $uid 用户id
     * @return Response
     * @throws \Exception
     */
    #[GetMapping]
    #[AuthAnnotation('getUserInfo', '*')]
    public function getUserInfo(int $uid): Response {
        return session('userInfo', callable: function ($info) use ($uid) {
            $userinfo = is_string($info) ? (
                json_decode($info, JSON_UNESCAPED_UNICODE) ?: []
            ) : $info;

            $user = (new userModel()) -> getUser($uid ?: $userinfo['uid']);

            return $user ?
                message() -> success('获取用户信息成功', $user)
                :message() -> unauthorized_error('用户不存在');
        });
    }

    /**
     * 退出登录
     * @return Response
     * @throws \Exception
     */
    #[DeleteMapping]
    #[AuthAnnotation('getUserInfo', '*')]
    public function loginOut(): Response
    {
        Session::delete();
        return message() -> success('退出登录成功');
    }

    /**
     * 更新用户信息
     * @param string $signature
     * @param string $email
     * @param string $avatar
     * @param string $nick_name
     * @return Response
     */
    #[PostMapping]
    #[AuthAnnotation('updateUserInfo', '*')]
    public function updateUserInfo(
        string $signature = '', string $email = '', string $avatar = '',
        string $nick_name = ''
    ): Response {
        $userInfo = [];
        if ($signature !== '') $userInfo['signature'] = $signature;
        if ($avatar !== '') $userInfo['avatar'] = $avatar;
        if ($email !== '') $userInfo['email'] = $email;
        if ($nick_name !== '') $userInfo['nick_name'] = $nick_name;

        $user = (new userModel()) -> update($userInfo, [
            'uid' => session('userInfo')['uid']
        ]);
        return message() -> success('修改信息成功', $user -> toArray());
    }

    /**
     * 绑定 手机或者邮箱
     * @param bindPhoneOrEmail $bindPhoneOrEmail
     * @return Response
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    #[PostMapping]
    #[AuthAnnotation('updateUserInfo', '*')]
    public function bindPhoneOrEmail(bindPhoneOrEmail $bindPhoneOrEmail): Response
    {
        return (new userModel()) -> bindPhoneOrEmail($bindPhoneOrEmail);
    }

    /**
     * 绑定第三方openid
     * @param string $openid
     * @param string $type
     * @return Response
     */
    #[PostMapping]
    #[AuthAnnotation('updateUserInfo', '*')]
    public function bindOauthOpenId(string $openid, string $type): Response
    {
        if ($type === "") return message() -> parameter_error('请选择需要绑定的平台');
        return (new userOauthKeyModel()) -> bindOpenId(session('userInfo')['uid'], $openid, $type);
    }

    /**
     * 账户注册
     * @param registerForm $registerForm
     * @return Response
     */
    #[PostMapping]
    public function register(registerForm $registerForm): Response
    {
        if ($registerForm -> email === '' && $registerForm -> phone === '') {
            return message() -> parameter_error('手机号或邮箱不能为空');
        }

        if ($registerForm -> passWord !== $registerForm -> confirmPassword) {
            return message() -> parameter_error('密码不一致, 重新输入');
        }
        return (new userModel()) -> createUser($registerForm);
    }

    /**
     * 更新密码
     * @param changePassword $changePassword
     * @return Response
     */
    #[PostMapping]
    public function changePassword(changePassword $changePassword): Response
    {
        return (new userModel()) -> changePassword($changePassword);
    }
}
